package cn.ahaoweb.drule.core.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @Name: 执行日志记录器
 * @Description:
 * @Author: wangzhonghao
 * @Date: 2025/2/14 14:40
 */
public class ExecuteLogger {

    private ExecuteLogger child;

    private List<Record> records = new ArrayList<>();

    public void add(String title, String content) {
        records.add(new Record(title, content));
    }

    /**
     * 添加执行记录
     *
     * @param title
     * @param content
     * @param print
     */
    public void add(String title, String content, boolean print) {
        records.add(new Record(title, content, print));
    }

    /**
     * 计算两个记录之间的时间差
     *
     * @param t1 标题1
     * @param t2 标题2
     * @return t2-t1 单位 ms
     */
    public String diffTimes(String t1, String t2) {
        Record r1 = getRecord(t1);
        Record r2 = getRecord(t2);
        return diff(r1, r2);
    }

    private static String diff(Record r1, Record r2) {
        if (r1 != null && r2 != null) {
            Long n2 = r2.getNanos();
            Long n1 = r1.getNanos();
            long l = (n2 - n1) / 1000;
            long mod = l % 1000;
            return l / 1000 + "." + (mod < 10 ? "00" + mod : (mod < 100 ? "0" + mod : mod));
        }
        return null;
    }

    public String getContent() {
        StringBuilder content = new StringBuilder();
        for (Record record : records) {
            if (record.print) {
                content.append(record.getTitle()).append(": ").append(record.getContent()).append("\n");
            }
        }
        return content.toString();
    }

    public String timesConsumeDetail() {
        Record pre = null;
        StringBuilder sb = new StringBuilder().append("\n");
        for (Record record : records) {
            if (pre == null) {
                pre = record;
                continue;
            }
            sb.append("  ").append(record.getTitle()).append(": ")
                    .append(diff(pre, record))
                    .append(" ms").append("\n");
            pre = record;
        }
        String diff = diff(records.get(0), pre);
        return diff + "ms" + sb;
    }

    public Record getRecord(String title) {
        for (Record record : records) {
            if (Objects.equals(title, record.getTitle())) {
                return record;
            }
        }
        return null;
    }

    public ExecuteLogger getChild() {
        return child;
    }

    public void setChild(ExecuteLogger child) {
        this.child = child;
    }

    public static class Record {
        // 标题
        private String title;

        // 时间(纳秒级)
        private Long nanos = System.nanoTime();

        // 内容
        private String content;

        // 是否输出
        private boolean print;

        public Record(String title, String content) {
            this(title, content, true);
        }

        public Record(String title, String content, boolean print) {
            this.title = title;
            this.content = content;
            this.print = print;
        }

        public String getTitle() {
            return title;
        }

        public String getContent() {
            return content;
        }

        public Long getNanos() {
            return nanos;
        }

        @Override
        public String toString() {
            return "Record{" +
                    "title='" + title + '\'' +
                    ", nanos=" + nanos +
                    ", content='" + content + '\'' +
                    '}';
        }
    }

    @Override
    public String toString() {
        return "ExecuteLogger{" +
                "records=" + records +
                '}';
    }
}
